package main

import (
	"fmt"
	"math/rand"
	"os"
	"os/signal"
	_ "runtime"
	_ "sync"
	"syscall"
	"time"
)

func main() {
	//	wg := new(sync.WaitGroup)
	//	wg.Add(1)

	//	go func() {
	//		defer wg.Done()
	//		defer fmt.Println("A.defer")

	//		func() {
	//			defer fmt.Println("B.defer")
	//			runtime.Goexit()
	//			fmt.Println("B")
	//		}()
	//		fmt.Println("A")
	//	}()
	//	wg.Wait()

	//	wg := new(sync.WaitGroup)
	//	wg.Add(2)

	//	go func() {
	//		defer wg.Done()

	//		for i := 0; i < 6; i++ {
	//			fmt.Println(i)
	//			if i == 3 {
	//				runtime.Gosched()
	//			}
	//		}
	//	}()
	//	go func() {
	//		defer wg.Done()
	//		fmt.Println("Hello world!")
	//	}()
	//	wg.Wait()

	//	data := make(chan int)
	//	exit := make(chan bool)

	//	go func() {
	//		for d := range data {
	//			fmt.Println(d)
	//		}
	//		fmt.Println("recv over.")
	//		exit <- true
	//	}()
	//	data <- 1
	//	data <- 2
	//	data <- 3
	//	close(data)
	//	fmt.Printf("send over.")
	//	<-exit // 等待退出通知。

	//	data := make(chan int, 3)
	//	exit := make(chan bool)

	//	data <- 1
	//	data <- 2
	//	data <- 3

	//	go func() {
	//		for {
	//			if d, ok := <-data; ok {
	//				fmt.Println(d)
	//			} else {
	//				break
	//			}

	//		}

	//		//		for d := range data {
	//		//			fmt.Println(d)
	//		//		}
	//		fmt.Println("recv over.")
	//		exit <- true
	//	}()
	//	data <- 4
	//	data <- 5
	//	data <- 6
	//	close(data)
	//	fmt.Printf("send over.")
	//	<-exit // 等待退出通知。
	//	a, b := make(chan int, 3), make(chan int)

	//	go func() {
	//		v, ok, s := 0, false, ""
	//		for {
	//			fmt.Printf(" case  %d - %t  - %s \n", v, ok, s)
	//			select { //从channel 接收数据
	//			case v, ok = <-a: //从channel读数据
	//				s = "a"

	//			case v, ok = <-b:
	//				s = "b"

	//			}
	//			if ok {
	//				fmt.Printf(" %s - %d \n", s, v)
	//			} else {
	//				os.Exit(0)
	//			}
	//		}
	//	}()

	//	for i := 0; i < 5; i++ {
	//		select { //随机从channel发送数据
	//		case a <- i: // 往channel写数据
	//		case b <- i:
	//		}
	//	}
	//	close(a)
	//	select {}

	//	t := NewTest()
	//	fmt.Println(t)
	//	wg := sync.WaitGroup{}
	//	wg.Add(3)

	//	sem := make(chan int, 1)

	//	for i := 0; i < 3; i++ {
	//		go func(id int) {
	//			defer wg.Done()
	//			sem <- 1
	//			for x := 0; x < 3; x++ {
	//				fmt.Println(id, x)
	//			}
	//			<-sem
	//		}(i)
	//	}
	//	wg.Wait()

	//	var wg sync.WaitGroup
	//	quit := make(chan bool)

	//	for i := 0; i < 2; i++ {
	//		wg.Add(1)
	//		go func(id int) {
	//			defer wg.Done()
	//			task := func() {
	//				fmt.Println(id, time.Now().Nanosecond())
	//				time.Sleep(time.Second)
	//			}
	//			for {
	//				select {
	//				case <-quit:
	//					return
	//				default:
	//					task()
	//				}
	//			}
	//		}(i)
	//	}
	//	time.Sleep(time.Second * 5)
	//	close(quit)
	//	wg.Wait()

	//	w := make(chan bool)
	//	c := make(chan int, 2)
	//	go func() {
	//		select {
	//		case v := <-c:
	//			fmt.Println(v)
	//		case <-time.After(time.Second * 3):
	//			fmt.Println("timeout:")
	//		}
	//		w <- true
	//	}()
	//	c <- 1 // 注释掉，引发 timeout。
	//	<-w

	//	req := NewRequest(10, 20, 30)
	//	Process(req)
	//	fmt.Println(<-req.ret)

	sigs := make(chan os.Signal, 1)
	done := make(chan bool, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		sig := <-sigs
		fmt.Println()
		fmt.Println(sig)
		done <- true
	}()
	fmt.Println("awaiting signal")
	<-done
	fmt.Println("exiting")

}
func Process(req *Request) {
	x := 0
	for _, i := range req.data {
		x += i
	}
	req.ret <- x
}

//channel 作为结构体
type Request struct {
	data []int
	ret  chan int
}

func NewRequest(data ...int) *Request {
	return &Request{data, make(chan int, 1)}
}

//工厂模式
func NewTest() chan int {
	c := make(chan int)
	rand.Seed(time.Now().UnixNano())
	go func() {
		time.Sleep(time.Second)
		c <- rand.Int()
	}()
	return c
}
